#ifndef AVLIMP_H
#define AVLIMP_H

#include "AVL.h"
#include "IteradorListaImp.h"
#include "Puntero.h"
#include "ListaImp.h"

template<class T>
class NodoAVL {
public:
				T dato;
				int balance;
				Puntero<NodoAVL<T>> izq;
				Puntero<NodoAVL<T>> der;
				NodoAVL()
				{
				
				}
				virtual ~ NodoAVL(){}
				bool operator==(NodoAVL<T> &n)
				{
					return dato==n.dato;
				}
				NodoAVL<T> &operator=(NodoAVL<T> &n)
				{
					dato=n.dato;
					balance=n.balance;
					izq=n.izq;
					der=n.der;
				}
};
template <class T>
class AVLImp : public AVL<T>
{
	
private:

		//struct nodoAVL;
		//typedef nodoAVLPtr nodoAVLPtr;

		//struct nodoAVL {
		//	T dato;
		//	nodoAVLPtr izq;
		//	nodoAVLPtr der;
		//	int balance;
		//};
		ListaImp<T> * lista;
		//Variables de Clase
        typedef Puntero<NodoAVL<T>> nodoAVLPtr;
		Puntero<NodoAVL<T>> Raiz;
		bool vario_h;
		int largo;
		//Metodos Auxiliares
		void insertar(const T &e,  nodoAVLPtr &n);
		void borrarArbolAux(nodoAVLPtr &n);
		void borrarElemento(const T e, nodoAVLPtr &n);
		const bool pertenece(const T &e, nodoAVLPtr &n);
		const void imprimirAux(nodoAVLPtr n);
		const void iteradorAux(nodoAVLPtr n);
		const void auxIterador(nodoAVLPtr n/*, ListaImp<T> & l*/);
		//Rotaciones
		void rotacionDobleD(nodoAVLPtr &n);
		void rotacionDobleI(nodoAVLPtr &n);
		void rotacionSimpleD(nodoAVLPtr &n);
		void rotacionSimpleI(nodoAVLPtr &n);
		void BalanceoD(nodoAVLPtr &n);
		void BalanceoI(nodoAVLPtr &n);

		Puntero<NodoAVL<T>> maximo(Puntero<NodoAVL<T>> n);
		int max(int a, int b);
		int altura(nodoAVLPtr n);

	public:

		//Constructoras
		AVLImp();
		void agregar(const T &e);
		virtual Puntero<Iterador<T>> ObtenerIterador() const;
		//Destructoras
		~AVLImp();
		void vaciar();
		void borrarArbol();
		void borrarNodo(const T e);
	    //typedef NodoAVL<T>* nodoAVL;
		//Selectoras
		T datoRaiz();

		//Predicados
		const bool esVacio();
		const bool esMiembro(const T &e);
		//Otras
		const void imprimir(); 
		const void CrearIterador();
		int Largo();

};
#include "AVLImp.cpp"
#endif